/*
 * AALItem.c
 *
 *  Created on: 17.05.2011
 *      Author: sili
 */

#include "AALItem.h"

static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("at.sili.aalsystem.model.AALItem"));

AALItem::AALItem(int _id, Controller * _controller){
	this->globalId=Tools::getNewGlobalId();
	this->id = _id;
	this->controller = _controller;
	this->visibility = 100;
	this->hotkey = -1;
	this->fixedHotkey = false;
	this->name.clear();
	this->type.clear();
	this->type.append("container");
	this->templateName.clear();
	this->parent = NULL;
	this->children.clear();

	AAL_TRACE(logger,"Constructor globalId:%d", AALItem::globalId);
}

AALItem::~AALItem() {
	AAL_DEBUG(logger,"Destructor globalId:%d", AALItem::globalId);
}

void AALItem::createHotkeys(){
	AAL_TRACE(logger, "CreateHotkeys for children of AALItem:id:%d", this->getId());
	eraseHotkeys(true);
	vector<AALItem*>::iterator entry = this->children.begin();
	while(entry != this->children.end()){
		AALItem * child = (*entry);
		if(!child->hasFixedHotkey()){
			int nextFreeHotkey = getNextFreeHotkey();
			child->setHotkey(nextFreeHotkey);
		}
		entry++;
	}
}

void AALItem::setId(int _id){
	this->id = _id;
}

int AALItem::getHotkey(){
	return this->hotkey;
}

void AALItem::setHotkey(int _hotkey){
	if(!fixedHotkey)
		this->hotkey = _hotkey;
}

bool AALItem::hasFixedHotkey(){
	return this->fixedHotkey;
}

void AALItem::setFixedHotkey(bool fixed){
	this->fixedHotkey = fixed;
	AAL_TRACE(logger, "Set fixed hotkey for aalItem %d, fixed %d, hotkey %d", this->id, this->fixedHotkey, this->hotkey);
}

const char * AALItem::getName(){
	return this->name.c_str();
}

void AALItem::setName(const char * _name){
	this->name.clear();
	this->name.append(_name);
}

const char * AALItem::getType(){
	return this->type.c_str();
}

/*
void AALItem::setType(const char * _type){
	this->type.clear();
	this->type.append(_type);
}
*/

const char * AALItem::getTemplateName(){
	return this->templateName.c_str();
}

void AALItem::setTemplateName(const char * _template){
	this->templateName.clear();
	this->templateName.append(_template);
}

int AALItem::getId(){
	return this->id;
}

bool AALItem::addOrReplaceChild(AALItem * _child){
	if(_child == NULL){
		AAL_WARN(logger, "Can't addOrReplaceChild _child because got an NULL instance.");
		return false;
	}

	aalItemMutex.Lock();
	AAL_DEBUG(logger, "Trying to addOrReplaceChild child-AALItem [globalId:%d, id:%d, name:%s] "
			"from parent-AALItem [globalId:%d, id:%d, name:%s]", _child->globalId, _child->getId(), _child->getName(), this->globalId, this->getId(), this->getName());
	vector<AALItem*>::iterator childrenIt;
	for (childrenIt=children.begin(); childrenIt<children.end(); childrenIt++ ){
		AALItem * toReplace = (AALItem *)(*childrenIt);
		if(_child->globalId == toReplace->globalId){
			// nothing to do, _child is the same instance as toReplace
			AAL_DEBUG(logger, "AddOrReplaceChild, nothing to do. Instances are equal.");
			aalItemMutex.Unlock();
			return true;
		} else {
			// this is a new child
			// search for the _child->getId()
			if(_child->getId() == toReplace->getId()){
				// this toReplace should be replaced by _child
				childrenIt = children.erase(childrenIt);
				delete(toReplace);
			}
		}
	}

	AAL_DEBUG(logger, "Adding new child-AALItem [globalId:%d, id:%d, name:%s] "
			"to parent-AALItem [globalId:%d, id:%d, name:%s].", _child->globalId, _child->getId(), _child->getName(), this->globalId, this->getId(), this->getName());
	_child->setParent(this);
	this->children.push_back(_child);
	aalItemMutex.Unlock();
	return true;
}

bool AALItem::eraseChild(AALItem * _child){
	if(_child == NULL){
		AAL_WARN(logger, "Can't delete _child because got an NULL instance.");
		return false;
	}
	aalItemMutex.Lock();
	bool done = false;
	AAL_DEBUG(logger, "Trying to erase child-AALItem [globalId:%d, id:%d, name:%s] "
			"from parent-AALItem [globalId:%d, id:%d, name:%s]", _child->globalId, _child->getId(), _child->getName(), this->globalId, this->getId(), this->getName());
	vector<AALItem*>::iterator childrenIt;
	for (childrenIt=children.begin(); childrenIt<children.end(); childrenIt++ ){
		if(_child==(*childrenIt)){
			children.erase(childrenIt);
			done = true;
		}
	}
	if(!done){
		AAL_WARN(logger, "Can't erase child-AALItem [globalId:%d, id:%d, name:%s] "
				"from parent-AALItem [globalId:%d, id:%d, name:%s] because it can't be found.", _child->globalId, _child->getId(), _child->getName(), this->globalId, this->getId(), this->getName());
	}
	aalItemMutex.Unlock();
	return done;
}

void AALItem::setParent(AALItem * _parent){
	this->parent = _parent;
}

AALItem * AALItem::getParent(){
	return this->parent;
}

void AALItem::resize(AALSize * _size, bool _recursive) {
	aalItemMutex.Lock();
	AAL_TRACE(logger, "Resize %s", this->name.c_str());
	this->controller->getTemplateFactory()->getTemplate(this->templateName.c_str(), this->image);

	if(this->image.columns() == 0 || this->image.rows() == 0){
		AAL_WARN(logger, "Can't get template %s for AALItem %d name %s", this->templateName.c_str(), this->id, this->name.c_str());
		aalItemMutex.Unlock();
		return;
	}

	if(_size != NULL){
		// first call with an given size
		AAL_TRACE(logger, "Resize with given size of w:%f, h:%f", _size->width, _size->height);

		this->image.scale(Magick::Geometry(_size->width, _size->height,0,0,false,false));

		int realWidth = this->image.columns();
		int realHeight = this->image.rows();

		this->area.left = 0;
		this->area.top = 0;
		this->area.width = realWidth;
		this->area.height = realHeight;
	} else {
		// following calls without given size -> use parent areas
		AAL_TRACE(logger, "Resize request without given size -> using parent %d", this->parent->getId());
		double wishWidth = this->parent->area.width / 100.0 * this->relativePositions.width;
		double wishHeight = this->parent->area.height / 100.0 * this->relativePositions.height;

		this->image.sample(Magick::Geometry(wishWidth, wishHeight,0,0,false,false));

		int realWidth = this->image.columns();
		int realHeight = this->image.rows();

		this->area.left = this->parent->area.width / 100.0 * this->relativePositions.left;
		this->area.top  = this->parent->area.height / 100.0 * this->relativePositions.top;
		this->area.width = realWidth;
		this->area.height = realHeight;
	}

	if(_recursive){
		vector<AALItem*>::iterator childrenIt;
		for (childrenIt=children.begin(); childrenIt<children.end(); childrenIt++ ){
			(*childrenIt)->resize(NULL, _recursive);
		}
	}
	aalItemMutex.Unlock();
}

void AALItem::toDOMElement(DOMDocument * _doc, DOMElement * _parentNode){
	aalItemMutex.Lock();
	AAL_TRACE(logger, "ToDOMElement, AALItem.id:%d number of children:%d", this->getId(), this->children.size());

	const int length = 100;
	XMLCh tempStr0[length];

	XMLString::transcode("AALItem", tempStr0, length-1);
	DOMElement * item = NULL;
	if(_parentNode != NULL){
		item = _doc->createElement(tempStr0);
	} else {
		item = (DOMElement *)_doc->getFirstChild();
	}

	toDOMElementParameters(item);

	vector<AALItem*>::iterator childrenIt;
	for (childrenIt=children.begin(); childrenIt<children.end(); childrenIt++ ){
		(*childrenIt)->toDOMElement(_doc, item);
	}
	if(_parentNode != NULL)
		_parentNode->appendChild(item);

	aalItemMutex.Unlock();
}

void AALItem::toDOMElementParameters(DOMElement * _selfNode){
	AAL_TRACE(logger, "ToDOMElementParameters AALItem.id:%d", this->getId());

	const int length = 100;
	char integerBuffer[length];
	XMLCh tempStr0[length];
	XMLCh tempStr1[length];

	snprintf(integerBuffer, (size_t)length, "%d", this->id);
	XMLString::transcode("id", tempStr0, length-1);
	XMLString::transcode(integerBuffer, tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);

	XMLString::transcode("name", tempStr0, length-1);
	XMLString::transcode(this->name.c_str(), tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);

	XMLString::transcode("type", tempStr0, length-1);
	XMLString::transcode(this->type.c_str(), tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);

	XMLString::transcode("templateName", tempStr0, length-1);
	XMLString::transcode(this->templateName.c_str(), tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);

	if(this->hasFixedHotkey() == true && this->hotkey != -1){
		AAL_DEBUG(logger, "Saving aalItem.id:%d and it's hotkey %d", this->id, this->hotkey);
		snprintf(integerBuffer, (size_t)length, "%d", this->hotkey);
		XMLString::transcode("hotkey", tempStr0, length-1);
		XMLString::transcode(integerBuffer, tempStr1, length-1);
		_selfNode->setAttribute(tempStr0,tempStr1);
	}

	snprintf(integerBuffer, (size_t)length, "%f", this->relativePositions.left);
	XMLString::transcode("relXPos", tempStr0, length-1);
	XMLString::transcode(integerBuffer, tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);

	snprintf(integerBuffer, (size_t)length, "%f", this->relativePositions.top);
	XMLString::transcode("relYPos", tempStr0, length-1);
	XMLString::transcode(integerBuffer, tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);

	snprintf(integerBuffer, (size_t)length, "%f", this->relativePositions.width);
	XMLString::transcode("relWidth", tempStr0, length-1);
	XMLString::transcode(integerBuffer, tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);

	snprintf(integerBuffer, (size_t)length, "%f", this->relativePositions.height);
	XMLString::transcode("relHeight", tempStr0, length-1);
	XMLString::transcode(integerBuffer, tempStr1, length-1);
	_selfNode->setAttribute(tempStr0,tempStr1);
}

void AALItem::fromDOMElement(DOMElement * _selfNode, int _currentDepth){

	fromDOMElementParameters(_selfNode);
	this->depth = _currentDepth;

	this->relativePositions.left = Tools::getDoubleAttributeValue(_selfNode, "relXPos");
	this->relativePositions.top = Tools::getDoubleAttributeValue(_selfNode, "relYPos");
	this->relativePositions.width = Tools::getDoubleAttributeValue(_selfNode, "relWidth");
	this->relativePositions.height = Tools::getDoubleAttributeValue(_selfNode, "relHeight");

	AAL_TRACE(logger, "FromDOMElement, AALItem.id:%d AALItem.name:%s AALItem.depth:%d", this->getId(), this->getName(), _currentDepth);
	DOMNodeList * childNodes = _selfNode->getChildNodes();
	int nextDepth = _currentDepth + 1;
	for(XMLSize_t childIndex = 0; childIndex < childNodes->getLength(); ++childIndex ){
		DOMNode * childNode = childNodes->item(childIndex);
		string childNodeName(XMLString::transcode(childNode->getNodeName()));
		if(childNodeName.find("AAL") != childNodeName.npos){
			DOMElement * child = (DOMElement*)childNode;
			int childId = Tools::getIntAttributeValue(child, "id");
			string childType = "";
			Tools::getStringAttributeValue(child, "type", &childType);
			AAL_TRACE(logger, "Seserialising child AALItem.id:%d AALItem.type:%s", childId, childType.c_str());
			AALItem * childAALItem = this->controller->createAALItem(childType.c_str(),childId);
			this->addOrReplaceChild(childAALItem);
			childAALItem->fromDOMElement(child, nextDepth);
		} else {
			AAL_WARN(logger, "Ignoring childNode of type != AAL* ");
		}
	}
}

void AALItem::fromDOMElementParameters(DOMElement * _selfNode, const char * _namespace){
	string buffer = "";
	string parameter = _namespace;
	parameter += "name";
	Tools::getStringAttributeValue(_selfNode, parameter.c_str(), &buffer);
	this->name = buffer;

	parameter = _namespace;
	parameter += "type";
	Tools::getStringAttributeValue(_selfNode, parameter.c_str(), &buffer);
	this->type = buffer;

	parameter = _namespace;
	parameter += "templateName";
	Tools::getStringAttributeValue(_selfNode, parameter.c_str(), &buffer);
	this->templateName = buffer;

	parameter = _namespace;
	parameter += "hotkey";
	Tools::getStringAttributeValue(_selfNode,parameter.c_str(),&buffer);

	AAL_DEBUG(logger, "Restoring aalItem.id:%d and it's hotkey %d", this->id, this->hotkey);
	if( buffer.compare("0") == 0 || buffer.compare("1") == 0 ||
		buffer.compare("2") == 0 || buffer.compare("3") == 0 ||
		buffer.compare("4") == 0 || buffer.compare("5") == 0 ||
		buffer.compare("6") == 0 || buffer.compare("7") == 0 ||
		buffer.compare("8") == 0 || buffer.compare("9") == 0){
		this->hotkey = atoi(buffer.c_str());
		this->setFixedHotkey(true);
	}
}

void AALItem::fromSVG(DOMDocument * _doc, DOMElement * _selfSvgNode, const char * _svgFile, const map<string, AALArea> & _svgAreas){

	string buffer = "";

	DOMNodeList * childNodes = _selfSvgNode->getChildNodes();
	for(XMLSize_t childIndex = 0; childIndex < childNodes->getLength(); ++childIndex ){
		DOMNode * childNode = childNodes->item(childIndex);
		Tools::getStringAttributeValue(childNode, "aal:type", &buffer);
		if(buffer.size() > 0){
			// this is an AAL group DOMNode
			DOMElement * aalDOMElement = (DOMElement *) childNode;
			int id = Tools::getIntAttributeValue(aalDOMElement,"aal:id");
			if(id < 0){
				// file doesn't exists -> warn and abort
				AAL_WARN(logger, "Can't get the aal:id from SVG for aal:type='%s'. Ignoring this group DOMNode !!!", buffer.c_str());
				continue;
			}
			AAL_DEBUG(logger, "Creating new AALItem as child of parentId:%d parentName:%s ", this->getId(), this->getName());

			AALItem * aalItem = this->controller->createAALItem(buffer.c_str(),id);
			this->addOrReplaceChild(aalItem);

			aalItem->fromDOMElementParameters(aalDOMElement, "aal:");

			// update Areas
			Tools::getStringAttributeValue(aalDOMElement, "id", &buffer);
			aalItem->updateArea(buffer.c_str(), _svgAreas);

			aalItem->fromSVG(_doc, aalDOMElement, _svgFile, _svgAreas);
		}
	}
}

void AALItem::updateArea(const char * _subId, const map<string, AALArea> & _svgAreas){

	map<string, AALArea>::const_iterator finder = _svgAreas.find(_subId);
	if(finder != _svgAreas.end()){
		AALArea matchArea = finder->second;
		this->area.left = matchArea.left;
		this->area.top = matchArea.top;
		this->area.width = matchArea.width;
		this->area.height = matchArea.height;

		// create relative positions

		if(this->parent != NULL){
			this->relativePositions.left = 100.0 / this->parent->area.width * (matchArea.left - this->parent->area.left);
			this->relativePositions.top = 100.0 / this->parent->area.height * (matchArea.top - this->parent->area.top);
			this->relativePositions.width = 100.0 / this->parent->area.width * matchArea.width;
			this->relativePositions.height = 100.0 / this->parent->area.height * matchArea.height;
		} else {
			this->relativePositions.left = 0.0;
			this->relativePositions.top = 0.0;
			this->relativePositions.width = 100.0;
			this->relativePositions.height = 100.0;
		}
	} else {
		AAL_WARN(logger, "Can't find %s, so can't update area. ",_subId);
	}
}

AALItem * AALItem::getFirstChild(){
	if(this->children.size() > 0){
		return * this->children.begin();
	}
	return NULL;
}

AALItem * AALItem::getAALItem(const int _aalItemId){
	AAL_TRACE(logger, "Searching for AALItem with id:%d in %s", _aalItemId, getName());

	if(this->getId() == _aalItemId){
		return this;
	}

	AALItem * finder = NULL;
	vector<AALItem*>::iterator entry = this->children.begin();
	while(entry != this->children.end()){
		finder = (*entry)->getAALItem(_aalItemId);
		if(finder != NULL)
			break;
		entry++;
	}

	return finder;
}

AALItem * AALItem::getAALItemByHotkey(const int _aalItemHotkey){
	if(this->hotkey == _aalItemHotkey){
		return this;
	}

	AALItem * finder = NULL;
	vector<AALItem*>::iterator entry = this->children.begin();
	while(entry != this->children.end()){
		finder = (*entry)->getAALItemByHotkey(_aalItemHotkey);
		if(finder != NULL)
			break;
		entry++;
	}
	return finder;
}

void AALItem::eraseHotkeys(bool _findRootFirst){
	if(_findRootFirst){
		if(this->parent != NULL){
			// I'm not the root
			this->parent->eraseHotkeys(_findRootFirst);
		}
	}

	// erase my key if not fixed
	if(!fixedHotkey)
		hotkey = -1;

	// erasse all my children recursive
	vector<AALItem*>::iterator entry = this->children.begin();
	while(entry != this->children.end()){
		(*entry)->eraseHotkeys();
		entry++;
	}
}

void AALItem::getFreeHotkeys(bool _findRootFirst, set<int> & _freeHotkeys){
	if(_findRootFirst){
		if(this->parent != NULL){
			// I'm not the root
			this->parent->getFreeHotkeys(_findRootFirst, _freeHotkeys);
		}
	}

	if(this->hotkey != -1){
		_freeHotkeys.erase(this->hotkey);
	}

	vector<AALItem*>::iterator entry = this->children.begin();
	while(entry != this->children.end()){
		(*entry)->getFreeHotkeys(false, _freeHotkeys);
		entry++;
	}
}

int AALItem::getNextFreeHotkey(){
	// delete not fixed hotkeys
	set<int> freeHotkeys;
	for (int i=1; i<100; i++) freeHotkeys.insert(i);
	getFreeHotkeys(true, freeHotkeys);
	int found = * freeHotkeys.begin();
	AAL_TRACE(logger, "GetNextFreeHotkey, found free hotkey %d ", found);
	return found;
}

void AALItem::renderHotkeys(DrawPane * _target, const int _renderDepth, int _currentDepth){
	int w = this->image.columns();
	int h = this->image.rows();

	if(this->visibility != 0 && this->hotkey != -1 && w > 0 && h > 0){
		AALLocation location;
		location.left = this->area.left + this->area.width / 2.0;
		location.top = this->area.top + this->area.height / 2.0;
		_target->DrawHotkey(location, this);
	}

	int childrenDepth = _currentDepth + 1;
	if(_currentDepth <= _renderDepth){
		vector<AALItem*>::iterator entry = this->children.begin();
		while(entry != this->children.end()){
			(*entry)->renderHotkeys(_target, _renderDepth, childrenDepth);
			entry++;
		}
	}
}

void AALItem::renderImage(DrawPane * _target, AALLocation * _location, const int _renderDepth, int _currentDepth){
	AAL_TRACE(logger, "RenderImage %d ", this->getId());
	_target->currentVisibleItems.push_back(this);
	int w = this->image.columns();
	int h = this->image.rows();
	int xOffset = int(floor(this->area.left));
	int yOffset = int(floor(this->area.top));
	if(_location != NULL){
		xOffset = _location->left;
		yOffset = _location->top;
	} else {
		xOffset += int(floor(this->parent->area.left));
		yOffset += int(floor(this->parent->area.top));
		AAL_TRACE(logger, "RenderImage, id:%d name:%s visibility:%d renderDepth:%d currentDepth:%d w:%d h:%d xOff:%d yOff:%d ",
				this->getId(), this->getName(), this->visibility, _renderDepth, _currentDepth, w, h, xOffset, yOffset);
	}
	this->area.left = xOffset;
	this->area.top = yOffset;

	if(this->visibility != 0 && w > 0 && h > 0){
		_target->DrawImage(cPoint(xOffset, yOffset), & this->image, this->visibility);
	}

	int childrenDepth = _currentDepth + 1;
	if(_currentDepth < _renderDepth){
		vector<AALItem*>::iterator entry = this->children.begin();
		while(entry != this->children.end()){
			(*entry)->renderImage(_target, NULL, _renderDepth, childrenDepth);
			entry++;
		}
	}
}

void AALItem::visualizeSelf(Visualizer * _visualizer, AALAction * _action){
	AAL_DEBUG(logger, "VisualizeSelf in %d action id is %ld", this->getId(), _action->id);
	const cFont * font = cFont::GetFont(fontOsd);

	if(		_action->type == doInfo ||
			_action->type == doWarn ||
			_action->type == doAlarm){

		if(_visualizer->getContentPane() != NULL){
			_visualizer->getContentPane()->Clear();

			// THIS IS A INFO, WARNING OR ALARM
			// don't set a background color to content pane cause the content pane should not be rendered

		}

		if(_visualizer->getInfoPane() != NULL){

			uint32_t bgColor = _visualizer->getBackgroundColorForAction(_action);
			_visualizer->getInfoPane()->colorBg = bgColor;

			_visualizer->getInfoPane()->Clear();

			// IT's a warning, it must be visible
			int oldVidibility = this->visibility;

			this->visibility = 100;
			// draw image
			AALSize wishSize;
			wishSize.width = _visualizer->getInfoPane()->area.width / 5.0;
			wishSize.height = _visualizer->getInfoPane()->area.height * 0.95;

			this->resize(&wishSize, true);

			AALLocation location;
			location.left = ((_visualizer->getInfoPane()->area.width - this->image.columns()));
			location.top = ((_visualizer->getInfoPane()->area.height - this->image.rows()) / 2.0);
			this->renderImage(_visualizer->getInfoPane(), & location , 1, 0);

			// draw text
			AALArea textArea;
			textArea.top = 10;
			textArea.left = 10;
			textArea.width = _visualizer->getInfoPane()->area.width - 2 * textArea.left;
			textArea.height = _visualizer->getInfoPane()->area.height - 2 * textArea.top;
			textArea.width -= this->image.columns();
			_visualizer->getInfoPane()->DrawText(textArea, _action->message.c_str(), _visualizer->getTextColor(), clrTransparent, font);
			this->visibility = oldVidibility;
		}
	} else {

		// DEFAULT VIEW, NO SIGNALS LIKE (info, alarm or warn)

		if(_visualizer->getContentPane() != NULL){

			uint32_t bgColor = _visualizer->getBackgroundColorForPane(DrawPane::contentPaneType);
			_visualizer->getContentPane()->colorBg = bgColor;

			_visualizer->getContentPane()->Clear();

			AALSize wishSize;
			wishSize.width = _visualizer->getContentPane()->area.width * 0.95;
			wishSize.height = _visualizer->getContentPane()->area.height * 0.95;

			this->resize(&wishSize, true);

			// draw image
			AALLocation location;
			location.left = ((_visualizer->getContentPane()->area.width - this->area.width) / 2.0);
			location.top = ((_visualizer->getContentPane()->area.height - this->area.height) / 2.0);
			this->renderImage(_visualizer->getContentPane(), & location , 1, 0);

			// create hotkeys (only for the first level depth)
			this->createHotkeys();
			this->renderHotkeys(_visualizer->getContentPane(), 1, 0);
		}

		if(_visualizer->getInfoPane() != NULL){

			uint32_t bgColor = _visualizer->getBackgroundColorForPane(DrawPane::infoPaneType);
			_visualizer->getInfoPane()->colorBg = bgColor;

			_visualizer->getInfoPane()->Clear();

			AALArea textArea;
			textArea.top = 10;
			textArea.left = 10;
			textArea.width = _visualizer->getInfoPane()->area.width - 2 * textArea.left;
			textArea.height = _visualizer->getInfoPane()->area.height - 2 * textArea.top;
			_visualizer->getInfoPane()->DrawText(textArea, this->name.c_str(), _visualizer->getTextColor(), clrTransparent, font);
		}
	}
}

eOSState AALItem::guiAction(eKeys _key){
	// nothing to do here...
	// see e.g. AALActorItem. It does something with this guiAction.
	return osContinue;
}

void AALItem::getFlatList(list<AALItem *> * _list, int _currentLevel){
	_list->push_back(this);
	vector<AALItem*>::iterator entry = this->children.begin();
	_currentLevel ++;
	while(entry != this->children.end()){
		AALItem * child = (*entry);
		child->getFlatList(_list,_currentLevel);
		entry++;
	}
}

bool AALItem::cloneRelatives(AALItem * _intoAALitem){
	vector<AALItem*>::iterator childrenIt;
	for (childrenIt=children.begin(); childrenIt<children.end(); childrenIt++ ){
		AALItem * child = (AALItem *)(*childrenIt);
		child->setParent(_intoAALitem);
	}
	return this->getParent()->addOrReplaceChild(_intoAALitem);
}
